package org.force4spring.query;

import java.util.ArrayList;
import java.util.List;


public class QueryImpl implements Query {
	private List<Expression> selectExpressions;
	private List<Expression> fromExpressions;
	private Expression whereExpression;
	private List<Expression> orderExpressions;
	private Integer limit;
	
	public QueryImpl() {
		selectExpressions = new ArrayList<Expression>();
		fromExpressions = new ArrayList<Expression>();
		orderExpressions = new ArrayList<Expression>();
	}
	
	/**
	 * @see org.force4spring.query.Expression#buildSOQL()
	 */
	public String buildSOQL() {
		StringBuffer soql = new StringBuffer();
		
		soql.append("SELECT ");
		for (int i=0;i<selectExpressions.size();i++) {
			if (i > 0) {
				soql.append(", ");
			}
			soql.append(selectExpressions.get(i).buildSOQL());
		}
		
		soql.append(" FROM ");
		for (int i=0;i<fromExpressions.size();i++) {
			if (i > 0) {
				soql.append(", ");
			}
			soql.append(fromExpressions.get(i).buildSOQL());
		}
		
		if (whereExpression != null) {
			soql.append(" WHERE ");
			soql.append(whereExpression.buildSOQL());
		}
		
		if (orderExpressions.size() > 0) {
			soql.append(" ORDER BY ");
			for (int i=0;i<orderExpressions.size();i++) {
				if (i > 0) {
					soql.append(", ");
				}
				soql.append(orderExpressions.get(i).buildSOQL());
			}
		}
		
		if (limit != null) {
			soql.append(" LIMIT ").append(limit);
		}
		return soql.toString();
	}

	/**
	 * @see org.force4spring.query.Query#addFromExpression(org.force4spring.query.Expression)
	 */
	public Query addFromExpression(Expression expression) {
		fromExpressions.add(expression);
		return this;
	}

	/**
	 * @see org.force4spring.query.Query#addSelectExpression(org.force4spring.query.Expression)
	 */
	public Query addSelectExpression(Expression expression) {
		selectExpressions.add(expression);
		return this;
	}

	/**
	 * @see org.force4spring.query.Query#getFromExpressions()
	 */
	public List<Expression> getFromExpressions() {
		return fromExpressions;
	}

	/**
	 * @see org.force4spring.query.Query#getSelectExpressions()
	 */
	public List<Expression> getSelectExpressions() {
		return selectExpressions;
	}

	/**
	 * @see org.force4spring.query.Query#getWhereExpression()
	 */
	public Expression getWhereExpression() {
		return whereExpression;
	}

	/**
	 * @see org.force4spring.query.Query#removeSelectExpression(org.force4spring.query.Expression)
	 */
	public void removeSelectExpression(Expression expression) {
		selectExpressions.remove(expression);
	}

	/**
	 * @see org.force4spring.query.Query#setWhereExpression(org.force4spring.query.Expression)
	 */
	public void setWhereExpression(Expression expression) {
		this.whereExpression = expression;
	}

	public Query addFromExpressions(List<Expression> expressions) {
		fromExpressions.addAll(expressions);
		return this;
	}

	public Query addSelectExpressions(List<Expression> expressions) {
		selectExpressions.addAll(expressions);
		return this;
	}

	/**
	 * @see org.force4spring.query.Query#getLimit()
	 */
	public Integer getLimit() {
		return limit;
	}

	/**
	 * @see org.force4spring.query.Query#setLimit(java.lang.Integer)
	 */
	public void setLimit(Integer limit) {
		this.limit = limit;
	}

	/**
	 * @see org.force4spring.query.Query#addOrderExpression(org.force4spring.query.Expression)
	 */
	public Query addOrderExpression(Expression expression) {
		orderExpressions.add(expression);
		return this;
	}

	/**
	 * @see org.force4spring.query.Query#getOrderExpressions()
	 */
	public List<Expression> getOrderExpressions() {
		return orderExpressions;
	}

	/**
	 * @see org.force4spring.query.Query#removeOrderExpression(org.force4spring.query.Expression)
	 */
	public Query removeOrderExpression(Expression expression) {
		orderExpressions.remove(expression);
		return this;
	}
	
}
